package com.djmw.mouse.solr;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Component;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.djmw.mouse.entity.JobSearchResult;
import com.djmw.mouse.entity.PositionSolr;

@Component
public class JobSearchDaoSolr {

    @Autowired
    SolrHelper solrHelper;

    public JobSearchResult search(Map<String, SearchFilter> facetQuery, PageRequest pageRequest) {
        SolrServer server = solrHelper.getDefaultServer();
        SolrQuery query = new SolrQuery();
        for (String key : facetQuery.keySet()) {
            SearchFilter filter = facetQuery.get(key);
            if (filter.operator == Operator.EQ) {
                query.addFilterQuery(filter.fieldName + ":" + filter.value);
            } else if (filter.operator == Operator.GT || filter.operator == Operator.GTE) {
                query.addFilterQuery(filter.fieldName + ":[" + filter.value + " TO *]");
            } else if (filter.operator == Operator.LT || filter.operator == Operator.LTE) {
                query.addFilterQuery(filter.fieldName + ":[* TO " + filter.value + "]");
            } else if (filter.operator == Operator.LIKE) {
                query.setQuery(StringUtils.join(filter.value.toString().split(" \t"), "+"));
            }
        }
        Iterator<Order> sort = pageRequest.getSort().iterator();
        while (sort.hasNext()) {
            Order order = sort.next();
            query.addSort(order.getProperty(), order.getDirection() == Direction.DESC ? ORDER.desc : ORDER.asc);
        }
        query.setStart(pageRequest.getOffset()).setRows(pageRequest.getPageSize());
        query.setFacet(true).addFacetField("company_name", "working_years", "salary_range", "type");
        try {
            QueryResponse response = server.query(query);
            PageImpl<PositionSolr> page = new PageImpl<PositionSolr>(response.getBeans(PositionSolr.class),
                    pageRequest, response.getResults().getNumFound());
            List<FacetField> facets = response.getFacetFields();
            return new JobSearchResult(page, facets);
        } catch (SolrServerException e) {
            e.printStackTrace();
            PageImpl<PositionSolr> page = new PageImpl<PositionSolr>(new ArrayList<PositionSolr>(), pageRequest, 0);
            return new JobSearchResult(page, new ArrayList<FacetField>());
        }
    }

}
